import { Inject, Injectable } from '@nestjs/common';
import { OrgSearchModel } from 'src/logical/account/models/orgSearch.model';
import { QueryModel } from 'src/logical/common/models/Query.model';
import { BaseService } from 'src/logical/common/services/base.service';
import { OrgModel } from '../models/org.model';
import { QueryOrgListModel } from '../models/queryOrgList.model';
import { BaseListResultModel } from 'src/logical/common/models/BaseListResult.model';
import { BaseResultModel } from 'src/logical/common/models/BaseResult.model';
import { Pagination } from 'src/logical/common/models/Pagination.model';
import { OrgInfoModel } from '../models/orgInfo.model';
import { SelectOrgModel } from '../models/selectOrg.model';
import { RpOrgEntity } from '../entity/org.entity';
import { InjectModel } from '@nestjs/sequelize';

@Injectable()
export class OrgService extends BaseService {
  constructor(
    @InjectModel(RpOrgEntity)
    private rpOrgEntity: typeof RpOrgEntity,
  ) {
    super();
  }

  async queryForListByOrgType(
    orgSearchModel: OrgSearchModel,
  ): Promise<BaseListResultModel<Array<OrgModel>>> {
    let rsl: OrgModel[] = [];

    try {
      let queryList: RpOrgEntity[] = [];
      const query = {
        orgType: null,
        upOrgId: null,
      };
      orgSearchModel.orgType
        ? (query.orgType = orgSearchModel.orgType)
        : delete query.orgType;
      orgSearchModel.upOrgId
        ? (query.upOrgId = orgSearchModel.upOrgId)
        : delete query.upOrgId;

      queryList = await this.rpOrgEntity.findAll({
        where: query,
        order: [['orgId', 'Asc']],
      });
      if (queryList.length) {
        queryList.forEach((entity) => {
          const orgModel: OrgModel = new OrgModel();
          for (const key in entity.get()) {
            if (Object.prototype.hasOwnProperty.call(entity.get(), key)) {
              orgModel[key] = entity.get()[key];
            }
          }
          rsl.push(orgModel);
        });

        return this.resultListData(rsl, 200, '', null);
      }
    } catch (error) {
      console.log(error);
      return this.resultListData([], 500, '查询失败', null);
    }
  }

  async getTreeByLevel(
    orgSearchModel: OrgSearchModel,
  ): Promise<BaseResultModel<any>> {
    const model = await this.rpOrgEntity.findByPk(orgSearchModel.upOrgId);
    let res: OrgInfoModel = new OrgInfoModel();

    for (const key in model.get()) {
      if (Object.prototype.hasOwnProperty.call(model.get(), key)) {
        res[key] = model.get()[key];
      }
    }

    try {
      await this.getChildOrgBylevel(res, orgSearchModel.orgType);
    } catch (error) {
      console.log(error);
      return this.getFailedResultData();
    }
    return this.getSuccessResultData(res);
  }

  async getChildOrgBylevel(parent: OrgInfoModel, level: number) {
    const orgId = parent.orgId;
    let treeModelList: Array<OrgInfoModel> = [];
    let entityList: Array<RpOrgEntity> = await this.rpOrgEntity.findAll({
      where: { upOrgId: orgId },
      order: [['orgId', 'Asc']],
    });

    entityList.forEach((entity) => {
      const model: OrgInfoModel = new OrgInfoModel();
      for (const key in entity.get()) {
        if (Object.prototype.hasOwnProperty.call(entity.get(), key)) {
          model[key] = entity.get()[key];
        }
      }
      treeModelList.push(model);
      if (level !== model.orgType) {
        this.getChildOrgBylevel(model, level);
      }
      if (treeModelList.length) {
        parent.children = treeModelList;
      }
    });
  }

  async getSunOrg(parent: OrgInfoModel) {
    const orgId = parent.orgId;
    let treeModelList: Array<OrgInfoModel> = [];
    let entityList: Array<RpOrgEntity> = await this.rpOrgEntity.findAll({
      where: {
        upOrgId: orgId,
      },
      order: [['orgId', 'Asc']],
    });

    for (let i = 0; i < entityList.length; i++) {
      const entity = entityList[i];
      const model: OrgInfoModel = new OrgInfoModel();
      for (const key in entity.get()) {
        if (Object.prototype.hasOwnProperty.call(entity.get(), key)) {
          model[key] = entity.get()[key];
        }
      }

      await this.getSunOrg(model);
      treeModelList.push(model);
    }

    if (treeModelList.length) {
      parent.children = treeModelList;
    }
  }

  async getSunOrgByTwoLevel(parent: OrgInfoModel) {
    const orgId = parent.orgId;

    let treeModelList: Array<OrgInfoModel> = [];
    let entityList: Array<RpOrgEntity> = await this.rpOrgEntity.findAll({
      where: {
        upOrgId: orgId,
      },
      order: [['orgId', 'Asc']],
    });

    for (let i = 0; i < entityList.length; i++) {
      const entity = entityList[i];
      const model: OrgInfoModel = new OrgInfoModel();

      for (const key in entity.get()) {
        if (Object.prototype.hasOwnProperty.call(entity.get(), key)) {
          model[key] = entity.get()[key];
        }
      }

      if (model.orgType < 2) {
        await this.getSunOrgByTwoLevel(model);
      }

      treeModelList.push(model);
    }

    if (treeModelList.length) {
      parent.children = treeModelList;
    }
  }

  async queryOrgList(
    queryModel: QueryOrgListModel,
  ): Promise<BaseListResultModel<OrgModel>> {
    let rsl: Array<OrgModel> = [];
    let queryList: Array<RpOrgEntity> = [];

    queryList = await this.rpOrgEntity.findAll({
      where: {
        upOrgId: queryModel.orgId ? queryModel.orgId : 0,
      },
      order: [['orgId', 'Asc']],
    });

    if (queryList.length) {
      queryList.forEach((entity) => {
        const orgModel: OrgModel = new OrgModel();

        for (const key in entity.get()) {
          if (Object.prototype.hasOwnProperty.call(entity.get(), key)) {
            orgModel[key] = entity.get()[key];
          }
        }

        rsl.push(orgModel);
      });
      return this.resultListData(rsl, 200, '查询成功！', null);
    } else {
      return this.resultListData(null, 200, '查询结果为空！', null);
    }
  }

  async queryForTree(orgId): Promise<BaseResultModel<OrgInfoModel>> {
    const model: RpOrgEntity = await this.rpOrgEntity.findByPk(orgId);
    const res: OrgInfoModel = new OrgInfoModel();

    for (const key in model.get()) {
      if (Object.prototype.hasOwnProperty.call(model.get(), key)) {
        res[key] = model.get()[key];
      }
    }

    try {
      await this.getSunOrg(res);
    } catch (error) {
      console.log(error);
      this.getFailedResultData();
    }
    return this.getSuccessResultData(res);
  }

  async queryForTreeByTwoLevel(orgId): Promise<BaseResultModel<OrgInfoModel>> {
    const model: RpOrgEntity = await this.rpOrgEntity.findByPk(orgId);
    const res: OrgInfoModel = new OrgInfoModel();
    for (const key in model.get()) {
      if (Object.prototype.hasOwnProperty.call(model.get(), key)) {
        res[key] = model.get()[key];
      }
    }

    try {
      await this.getSunOrgByTwoLevel(res);
    } catch (error) {
      return this.getFailedResultData();
    }
    return this.getSuccessResultData(res);
  }

  async detail(orgId): Promise<BaseResultModel<OrgInfoModel>> {
    const org = await this.rpOrgEntity.findByPk(orgId);
    if (!org) {
      return this, this.getFailedResultData();
    }

    const res: OrgInfoModel = new OrgInfoModel();
    for (const key in org.get()) {
      if (Object.prototype.hasOwnProperty.call(org.get(), key)) {
        res[key] = org.get()[key];
      }
    }

    return this.getSuccessResultData(res);
  }

  async save(detail: OrgModel, tokenInfo): Promise<BaseResultModel<any>> {
    const entity: RpOrgEntity = new RpOrgEntity();

    for (const key in detail) {
      if (Object.prototype.hasOwnProperty.call(detail, key)) {
        entity[key] = detail[key];
      }
    }
    if (!entity.orgId) {
      entity.orgId = this.nextId();
    }
    try {
      await RpOrgEntity.upsert(entity.get());
      return this.saveSuccessResultData();
    } catch (error) {
      console.log(error);
      return this.saveFailedResultData('保存失败！');
    }
  }

  async delete(orgId): Promise<BaseResultModel<any>> {
    try {
      await RpOrgEntity.destroy({
        where: { orgId },
      });
      return this.deleteSuccessResultData();
    } catch (error) {
      return this.deleteFailedResultData('删除失败');
    }
  }
}
